perm filename SAIL.NEW[UP,DOC]8 blob sn#094747 filedate 1974-04-03 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00029 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00005 00002
C00007 00003	SAIL Addendum  1                                    TABLE OF CONTENTS
C00010 00004	SAIL Addendum  1                                    TABLE OF CONTENTS
C00013 00005	SAIL Addendum  1                                         INTRODUCTION
C00016 00006	SAIL Addendum  1                                   NUMERICAL ROUTINES
C00019 00007	SAIL Addendum  1                                   NUMERICAL ROUTINES
C00022 00008	SAIL Addendum  1                                   NUMERICAL ROUTINES
C00024 00009	SAIL Addendum  1                                 NEW PROCESS FEATURES
C00027 00010	SAIL Addendum  1                                 NEW PROCESS FEATURES
C00030 00011	SAIL Addendum  1                                 NEW PROCESS FEATURES
C00032 00012	SAIL Addendum  1                                       ERROR HANDLING
C00035 00013	SAIL Addendum  1                                       ERROR HANDLING
C00040 00014	SAIL Addendum  1                                       ERROR HANDLING
C00042 00015	SAIL Addendum  1                           INEXHAUSTIBLE STRING SPACE
C00046 00016	SAIL Addendum  1                           INEXHAUSTIBLE STRING SPACE
C00049 00017	SAIL Addendum  1                                              WRITEON
C00052 00018	SAIL Addendum  1                                              WRITEON
C00055 00019	SAIL Addendum  1                                              WRITEON
C00058 00020	SAIL Addendum  1                                              WRITEON
C00062 00021	SAIL Addendum  1                                              WRITEON
C00066 00022	SAIL Addendum  1                                              WRITEON
C00069 00023	SAIL Addendum  1                                              WRITEON
C00072 00024	SAIL Addendum  1                           MISCELLANEOUS NEW FEATURES
C00075 00025	SAIL Addendum  1                           MISCELLANEOUS NEW FEATURES
C00078 00026	SAIL Addendum  1                           MISCELLANEOUS NEW FEATURES
C00081 00027	SAIL Addendum  1                           MISCELLANEOUS NEW FEATURES
C00084 00028	SAIL Addendum  1                           MISCELLANEOUS NEW FEATURES
C00087 00029	
C00088 ENDMK
C⊗;



STANFORD ARTIFICIAL INTELLIGENCE LABORATORY                APRIL 1974






                          SAIL USER MANUAL

                               UPDATE



                            James R. Low
                           John F. Reiser
                           Hanan J. Samet
                          Robert F. Sproull
                         Daniel C. Swinehart
                          Russell H. Taylor
                           Kurt A. VanLehn










                              ABSTRACT

This document describes recent changes to the SAIL language since the
"new" manual (AIM-204) was  published in July 1973.  It  reflects the
various  new  features implemented  as  of 26  March,  1974  for SAIL
version  7 and  corrects  a number  of  minor errors  in  the earlier
manual.
SAIL Addendum  1                                    TABLE OF CONTENTS


  
                  T A B L E   O F   C O N T E N T S
                  _ _ _ _ _   _ _   _ _ _ _ _ _ _ _



SECTION                                                          PAGE



1    INTRODUCTION                                                   1



2    NUMERICAL ROUTINES                                             2

     1    OVERFLOW                                                  3
     2    ENTRY POINTS                                              4


3    NEW PROCESS FEATURES                                           5

     1    SPROUT APPLY                                              5
     2    SPROUT_DEFAULTS                                           5
     3    SUSPEND                                                   7
     4    FAIL AND SUCCEED                                          7


4    ERROR HANDLING                                                 8

     1    ERROR MODES                                               8
     2    USER ERROR PROCEDURES                                     8


5    INEXHAUSTIBLE STRING SPACE                                    11



6    WRITEON                                                       13

     1    Definition                                               13
     2    Example                                                  14
     3    Runtime particulars                                      15
     4    Using WRITEON for other purposes                         18
SAIL Addendum  1                                    TABLE OF CONTENTS


7    MISCELLANEOUS NEW FEATURES                                    20

     1    NEW MTAPE OPTIONS                                        20
     2    INITIALIZATION PHASES                                    20
     3    CHNCDB                                                   21
     4    ARRCLR                                                   21
     5    SETPL                                                    21
     6    EVALREDEFINE                                             22
     7    CVPS                                                     22
     8    EXPRESSIONS IN REQUIRES                                  22
     9    RELEASE                                                  22
     10   TTYUP                                                    22
     11   BREAKSET MODES "K" AND "F"                               23
     12   INOUT                                                    23
     13   GETSTS & SETSTS                                          23
     14   CHANGES TO "OPEN" ERROR HANDLING                         24
     15   ASH                                                      24
     16   ARG_LIST                                                 24
SAIL Addendum  1                                         INTRODUCTION


                             SECTION  1
                             _______  _

                            INTRODUCTION
                            ____________





The following short manual  describes the changes that  have happened
to  SAIL  since  the  publishing  of  the  Manual  in  July  1973. It
accurately reflects the state of SAIL, version 7, which was put up on
December 4, 1973.  The reader should be warned that many of these new
features were designed for veteran SAIL hackers.

The reader may also want  to refer to the following  documents, which
are usually kept updated.

MACLIE.WRU[DOC,AIL] A  summary  of commonly  made  errors  when using
                    macros and what to do about them.

TUTOR.DOC[DOC,AIL]  In introduction to LEAP.

LEAP.WRU[DOC,AIL]   A detailed description of the runtime environment
                    of LEAP for the  hardy few who want  to interface
                    to LEAP in assembly language.

SAIL.DOC[AIM,DOC]   The  July  '73  manual  (AIM-204)  in  LPT  form.
                    Warning: this  version is the  Stanford character
                    set.  It is also almost 300 pages long.   You can
                    get a  120 page  version, set  in two  columns of
                    nice type from the National Technical Information
                    Service, Springfield, Virginia 22151.

LIES[DOC,AIL]       This  file  contains  the  know  mistakes  in the
                    Manual.  Soon  it  will  also  contain  the known
                    mistakes in this document.













                                  1
SAIL Addendum  1                                   NUMERICAL ROUTINES


                             SECTION  2
                             _______  _

                         NUMERICAL ROUTINES
                         _________ ________





A collection of numerical routines has been added to SAIL.  These are
pre-declared in the compiler,  and are loaded from the  standard SAIL
library.   The  functions  are  quite  standard;  following  are  the
equivalent definitions:

1.  The standard trigonometric functions.  ASIN, ACOS, ATAN and ATAN2
    return results in radians.   The ATAN2 call takes  arc-tangent of
    the  quotient  of  its  arguments;  in  this  way,  it  correctly
    preserves sign information.

        REAL PROCEDURE SIN (REAL RADIANS);
        REAL PROCEDURE COS (REAL RADIANS);
        REAL PROCEDURE SIND (REAL DEGREES);
        REAL PROCEDURE COSD (REAL DEGREES);

        REAL PROCEDURE ASIN (REAL ARGUMENT);
        REAL PROCEDURE ACOS (REAL ARGUMENT);
        REAL PROCEDURE ATAN (REAL ARGUMENT);
        REAL PROCEDURE ATAN2 (REAL NUMERATOR,DENOMINATOR);


2.  The hyperbolic trigonometric functions.

        REAL PROCEDURE SINH (REAL ARGUMENT);
        REAL PROCEDURE COSH (REAL ARGUMENT);
        REAL PROCEDURE TANH (REAL ARGUMENT);

3.  The square-root function:

        REAL PROCEDURE SQRT (REAL ARGUMENT);

4.  A pseudo-random number  generator.  The argument specifies  a new
    value for the seed (If the  argument is 0, the old seed  value is
    used.  Thus to get differing random numbers, this argument should
    be zero.)  Results are normalized to lie in the range [0,1].

        REAL PROCEDURE RAN (INTEGER SEED);




                                  2
SAIL Addendum  1                                   NUMERICAL ROUTINES


5.  Logarithm and exponentiation functions.  These functions  are the
    same ones used by the SAIL exponentiation operator.  The  base is
    e  (2.71828182845904).  The  logarithm  to the  base 10  of  e is
    .4342944819.

        REAL PROCEDURE LOG (REAL ARGUMENT);
        REAL PROCEDURE EXP (REAL ARGUMENT);

These functions may occasionally be asked to compute numbers that lie
outside the range of legal floating-point numbers on the  PDP-10.  In
these cases,  the routines  issue sprightly  error messages  that are
continuable.



2.1 - OVERFLOW
      ________


In order  to better  perform their tasks,  these routines  enable the
system interrupt facility  for floating-point overflow  and underflow
errors.  If  an underflow is  detected, the results  are set to  0 (a
feat not  done by  the PDP-10  hardware, alas).   Be aware  that such
underflow fixups will be done to every underflow that occurs  in your
program.

If you would like to be informed of any numerical exceptions, you can
call the runtime:

        TRIGINI ( LOCATION(simple-procedure-name) );

Every floating-point exception that is not expected by  the interrupt
handler (the numerical routines use a special convention  to indicate
that  arithmetic exception  was  expected) will  cause  the specified
simple procedure to  be called.  This  procedure may look  around the
world as  described in  the Manual  for 'export'  interrupt handlers,
page 79.   If no  TRIGINI call  is done,  the interrupt  routine will
simply dismiss unexpected floating-point interrupts.












                                  3
SAIL Addendum  1                                   NUMERICAL ROUTINES


2.2 - ENTRY POINTS
      _____ ______


In order to avoid confusion (by the loader) with older trig packages,
the  entry points  of the  SAIL arithmetic  routines all  have  a "$"
appended  to the  end.   Thus, SIN  has  the entry  point  SIN$, etc.
WARNING:  If a  program  plans to  use the  SAIL  intrinsic numerical
routines, it should NOT include external declarations to  them, since
this will probably cause the FORTRAN library routines to be loaded.








































                                  4
SAIL Addendum  1                                 NEW PROCESS FEATURES


                             SECTION  3
                             _______  _

                        NEW PROCESS FEATURES
                        ___ _______ ________







3.1 - SPROUT APPLY
      ______ _____


The <procedure call> in a SPROUT statement may be an APPLY construct.
In  this case SPROUT will  do the "right" thing  about setting up the
static link  for  the  APPLY. That is,  "up-level" references  by the
process will  be made to  the same variable  instances that  would be
used if the APPLY did not  occur in a SPROUT statement. (See  page 77
of the manual.)

However, there  is a glitch.  The sprout mechanism  is not  yet smart
enough to find out the block of the declaration of the procedure used
to define the procedure item. It would be nice if it did,  since then
it could warn the user when that block was exited and yet the process
was still alive,  and thus potentially  able to refer  to deallocated
arrays and etc. What the sprout does instead is assume  the procedure
was declared in the outer  block. This may be fixed   eventually, but
in the meantime  some extra  care should be taken  when  using  apply
in   sprouts  to    avoid    exiting  a    block    with  dependents.
Similarly,  be warned   that the  "DEPENDENTS  (<blockid>)" construct
may  not give  the  "right"  result  for  sprout applies. Page  68 of
the Manual contains the description of this protection  mechanism for
non-APPLY Sprouts.



3.2 - SPROUT_DEFAULTS
      _______________


SAIL  now provides  a mechanism  by which  the user  may specify  the
"default" options to be used when individual procedures are sprouted.








                                  5
SAIL Addendum  1                                 NEW PROCESS FEATURES



Syntax:
        PROCEDURE <procid> ...
         BEGIN
         <some declarations>;
         SPROUT_DEFAULTS <integer constant>;
         <perhaps some more declarations>;
         :
         :
         <statements>
         :
         END;


In other words, SPROUT_DEFAULTS is a declaration.

Semantics:

If  one of the "allocation" fields of  the options word passed to the
SPROUT routine -- i.e. QUANTUM,STRINGSTACK,PSTACK, or  PRIORITY -- is
zero,   then  SPROUT  will look  at  the corresponding  field of  the
specified <integer constant> for the procedure being sprouted. If the
field is  non-zero,   then  that value  will be  used; otherwise  the
current "system" default will be used.

NOTE:  SPROUT_DEFAULTS  only  applies  to  "allocations",  i.e.   the
process status control bits (e.g. SUSPME) are not affected.
Example:

        RECURSIVE PROCEDURE FOO;
         BEGIN
         SPROUT_DEFAULTS STRINGSTACK(10);
         INTEGER XXX;
         :
         :
         END;
        :
        SPROUT(P1,FOO,STRINGSTACK(3));
        SPROUT(P2,FOO);
        COMMENT P1 will have a string stack of 3*32 words.
         P2 will have a string stack of 10*32 words;








                                  6
SAIL Addendum  1                                 NEW PROCESS FEATURES


3.3 - SUSPEND
      _______


SUSPEND now behaves like RESUME in that it returns an item.

        itm ← SUSPEND(<process item>)

Frequently, one is suspending some other process than the one that is
executing the SUSPEND statement.  In this case, the item  returned is
ANY.   However, in cases like:

        X ← SUSPEND(MYPROC);

where the process suspends itself, it might happen that  this process
is  made running  by a  RESUME from  another process.  If so,  then X
receives the <return_item>  that was an argument to the RESUME.



3.4 - FAIL AND SUCCEED
      ____ ___ _______


FAIL and SUCCEED now behave like RESUME and SUSPEND in that they also
return  an  item.   The  item returned  is  ANY  unless  the Matching
Procedure  containing  the FAIL  or  SUCCEED was  (1)  sprouted  as a
process, and (2) made running  by a RESUME construct.  In  the latter
case, the item returned is the <return_item> that was an  argument to
the RESUME.  [Note that the  only case in which a  Matching Procedure
can be reactivated at a FAIL is by being RESUMEd.]




















                                  7
SAIL Addendum  1                                       ERROR HANDLING


                             SECTION  4
                             _______  _

                           ERROR HANDLING
                           _____ ________







4.1 - ERROR MODES
      _____ _____


SAIL's error  handler has at  long last been  modified to do  what is
claimed it will do  in Section 20 of the manual (pgs 95 - 97), and in
the description of USERERR (pg 42).  In brief, it allows one to  have
error  messages automatically  sent  to  a "log"  file  while one  is
compiling, and to use USERERR as a trace statement.

The description given in the manual differs from reality in two ways:
"Keep" mode has not  been implemented (the error handler   will flush
all type-ahead except  a <lf>);   all  of the  other  modes ("Quiet",
"Logging",  and "Numbers")  are  implemented ONLY   IN  THE COMPILER.
However, one  can get the effect of error modes at runtime by using a
brand new feature called user error procedures.



4.2 - USER ERROR PROCEDURES
      ____ _____ __________


A  user error  procedure is a  user procedure  that is run  before or
instead of  the  SAIL error  handler  everytime  an error  occurs  at
runtime.  This  includes all array errors, IO  errors, Leapish errors
and all USERERRs.  It does not include system errors, such as Ill Mem
Ref or Ill UUO.

The  procedure one uses  for a  user error procedure  must be  of the
following type:

    SIMPLE INTEGER PROCEDURE proc (INTEGER loc; STRING msg, rsp);


Only the names  proc, loc,  msg, and rsp  may vary  from the  example
above, except  that one  may declare  the procedure  INTERNAL if  one
wishes to use it across files.



                                  8
SAIL Addendum  1                                       ERROR HANDLING


Whenever  the external integer _ERRP_  is loaded with LOCATION(proc),
the error handler will  call proc before it  does anything else.   It
will set loc to  the core location of the call  to the error handler.
Msg  will be  the message  that it  would have  printed.  Rsp will be
non-NULL only  if the  error was  from a  USERERR which  had response
string argument.  Proc can  do anything that  a simple  procedure can
do.  When it  exits, it should  return  an  integer which   tells the
error handler  if  it should do anything more.  If the integer  is 0,
the  error  handler will  (1)   print the   message,  (2)   print the
location,  and  (3)  query  the  tty  and  dispatch  on  the response
character (i.e ask for a <cr>, <lf>, etc.).  If the right half of the
integer is  non-zero, it  is taken as  the ascii  for a  character to
dispatch upon.  The left half may have two bits to  control printing.
If bit 17  in the integer is  on, message printing is  inhibited.  If
bit 16 is on, then  the location printing is inhibited.  For example,
"X"+(1 LSH 18) will cause the location to be printed and  the program
exited.  "C"+(3 LSH  18)  will cause  the error  handler  to continue
without printing anything.

Note that simple  procedures can not do  a non-local GOTO.   However,
the  effect of  a non-local  GOTO  can be  achieved in  a  user error
procedure by loading the external integer _ERRJ_ with the LOCATION of
a label. The label  should be a on  a call to a  non-simple procedure
which does the desired GOTO.  The error handler clears  _ERRJ_ before
calling the procedure  in  _ERRP_.  If  _ERRJ_  is non-zero  when the
user procedure returns, and continuing was specified, then  the error
handler's exit  consists of a simple transfer to  that location.

WARNING! Handling errors from strange places like the  string garbage
collector and  the core  management routines will  get you  into deep
trouble.

A  user error  procedure  has been  written which  gives  a traceback
through the run-time stack.  The traceback routine lists the  name of
each non-simple calling procedure and the location (in octal)  of the
PUSHJ it did,  starting with the  most recently called  procedure and
ending with the main procedure of the current process.

The  procedure  is currently  available  via  REQUIRE "LIBSA7[1,JFR]"
LIBRARY or via REQUIRE "WALK.REL[1,JFR]" LOAD_MODULE.   The procedure
will move to the system LIBSA7 as soon as possible.

To  use  the procedure  say  EXTERNAL PROCEDURE  _TRON_;  ... _TRON_;
COMMENT _TRON_ is for "trace on";.

Subsequent run-time errors will give the traceback, then  request the
usual  response.  To  get  the traceback  at any  time,  say EXTERNAL


                                  9
SAIL Addendum  1                                       ERROR HANDLING


PROCEDURE WALK; ... WALK;.  This can be useful in  checking recursion
level or in other debugging.

To  intercept the  trackback, say  EXTERNAL  PROCEDURE UMWALK(INTEGER
LOC);       ...        UMWALK(LOCATION(user_procedure));.        Then
user_procedure("NAME",LOC) is called once for every procedure  in the
traceback  chain,  instead  of  printing  "CALLED  FROM  "&NAME&"  AT
"&CVOS(LOC)&CRLF on the terminal.

To  discontinue  tracing  on errors:   EXTERNAL  INTEGER  _ERRP_; ...
_ERRP_←0;.






































                                 10
SAIL Addendum  1                           INEXHAUSTIBLE STRING SPACE


                             SECTION  5
                             _______  _

                     INEXHAUSTIBLE STRING SPACE
                     _____________ ______ _____





The string garbage collector has been modified to expand string space
(using discontiguous blocks) whenever necessary to satisfy the demand
for places to put strings. To take advantage  of  this  feature,  one
need not change his programs.

Here are some points which might be of interest, however:

1)  Although  we  are  going  to  provide  user control over all size
    parameters  eventually,  currently  only   the   initial   string
    space size  is   settable  by  the   user, either via  REQUIRE or
    the ALLOC  sequence, as  before.  The size  of each  string space
    increment will be  the same as the original size, which  need not
    be monstrous  any more  unless you   know that  all runs  of your
    program  will  need   a monstrous   string  space   anyhow.   The
    threshold  (see below)  for  expanding will  be set  at  1/8  the
    string  space  size  (increment size).

2)  One can, in his program, modify these values independently, if he
    is  willing  to use  the  USERCON function,  and  to  follow this
    format:

     USER TABLE ENTRY NAME              VALUE
        STINCR          lh: number of chars. in increment
                        rh: number of words in increment + 4

        STREQD          lh: number of chars. in threshold
                        rh: number of words in threshold.


3)  The threshold.   After garbage  collection, let  us say  that M-1
    discontiguous string spaces  are   full,  and  the  M'th   has  n
    free  characters in it (available for new strings).  The  garbage
    collector  was  called because   some routine wanted to  create a
    string R characters long, and there were not that many  available
    (free).      After    garbage  collection,   the   new  algorithm
    requires  that N  be greater  than R+LH(STREQD).   If it  is not,
    expansion  takes  place  (to  M+1  spaces),  to    satisfy   this
    requirement.    In other words, if STREQD is 1/8 the size  of the
    current space, that space  will not be  allowed  to  become  more


                                 11
SAIL Addendum  1                           INEXHAUSTIBLE STRING SPACE


    than   about   7/8   full.   This  helps  avoid  frequent, nearly
    useless calls on the garbage collector when  space is about gone.
    All  but the  current  space are  allowed  to become  as  full as
    possible, however.

4)  New  statistics  are  maintained  by  the    garbage   collector.
    Soon there   will  be  a built-in  routine you  can use  to print
    them.  For now, you may look at them using USERCON, although this
    document   does  not   say  what   they   are.      In   order to
    activate timing  of the  garbage collector  (slows it  down), set
    SGCTIME in the  user  table to -1.

5)  Future plans.  The  new  structure  not only allows  expansion of
    string  space,  it  also  will   allow   for    partial   garbage
    collections   (no   visible  benefits   except   increased speed,
    since  a partial  collection  will be  almost as  effective  as a
    complete one,  and  much   faster),  and  the  ability   to  move
    string  space  blocks, in order to compact memory.  Push  on your
    local representative  to  get  these  things done.






























                                 12
SAIL Addendum  1                                              WRITEON


                             SECTION  6
                             _______  _

                               WRITEON
                               _______





Note. As of  March 26, l974, the  following feature is  not available
from the  SAIL system on  [1,3], but does  exist on [1,JFR]  in files
SAIL.DMP and LIBSA7.REL.  The feature will become available  from the
system SAIL as soon as possible.

****** FURTHER NOTE: This feature may look somewhat different  by the
time   it  is   actually  incorporated   into  the   system   --  RHT
**************

SAIL now has  a WRITEON feature similar  to the WRITEON  statement of
ALGOLW.  SAIL WRITEON consists of a new key-word statement (WRITEON),
a pre-declared initialization procedure (WR_INI), and runtime support
routines.  The  WRITEON statement takes  an arbitrary number  of SAIL
expressions as parameters,  produces a string representation  of each
expression, concatenates the strings, and writes the resulting string
to the terminal and to a file.



6.1 - Definition
      __________


The syntax of WRITEON is

        WRITEON(<exp1>,<exp2>, ... ,<expn>)


where <exp1>,<exp2>, ... ,<expn> are SAIL expressions.

A  string  representation of  each  expression is  produced  and then
output.  The expressions are processed in order from left to right.

Type of <exp>   String representaion of <exp>

    STRING      <exp> itself
    INTEGER     CVS(<exp>)
    REAL        CVG(<exp>)
    ITEM        the PNAME of the item, if it has one [the items
                ANY, BINDIT, MAINPI, and EVENT_TYPE are normally
                considered to have PNAMES];

                                 13
SAIL Addendum  1                                              WRITEON


                else "ITEM_"&CVS(CVN(<exp>))

    SET         if <exp>={} then "PHI" else "{"& <string
                representation of each item in the set> &"}"

    LIST        if <exp>={{}} then "NIL" else "{{"& <string
                representation of each item in the list> &"}}"

    array       concatenation of the string representation of 
                each element of the array; the elements are
                taken in ascending memory location order


The initialization procedure is


        WR_INI("DEVICE","FILE",CHANNEL,MAXLENGTH)


where DEVICE  is a device  name, FILE  is a file  name, CHANNEL  is a
system  channel number,  and MAXLENGTH  is the  number  of characters
desired per line.

If FILE is not NULL, then DEVICE:FILE is OPENed for output on channel
CHANNEL, and then ENTERed.  Subsequent WRITEON statements will direct
output to  this channel/file, independent  of whether output  is also
going to the  terminal.  If FILE  is NULL, then  no OPEN or  ENTER is
done, and subsequent WRITEON statements will not direct output to any
file except the terminal.

Remember to CLOSE(CHANNEL) if the file is to be made permanent.



6.2 - Example
      _______


The following is an actual example of a program using WRITEON.

BEGIN "WRTEST"
EXTERNAL INTEGER WR_CHN;
EXTERNAL STRING WR_S1,WR_S2,WR_S3,WR_S4;
REQUIRE PNAMES; REQUIRE 10 NEW_ITEMS;
INTEGER J,K; ITEMVAR ITB; INTEGER ITEM ITA,ITB;
REAL PI; STRING GREET; SET S; LIST L;
STRING ARRAY ALPHABET[1:26]; INTEGER ARRAY EVENS[0:9];

DEFINE CRLF="('15&'12)", TAB="'11";

                                 14
SAIL Addendum  1                                              WRITEON



J←7; PI←3.14159265; ITVA←ITA; GREET←"HELLO"; DATUM(ITA)←117;
PUT ITB IN S; PUT ITA IN S;
PUT ITA IN L; PUT NEW IN L; PUT ITB IN L;
FOR K←0 STEP 1 UNTIL 9 DO EVENS[K]←K+K;
FOR K←1 STEP 1 UNTIL 26 DO 
        ALPHABET[K]←"ABCDEFGHIJKLMNOPQRSTUVWXYZ"[K FOR 1];

COMMENT SET SPACING BETWEEN WRITEONS; WR_S1←CRLF;
COMMENT SET SPACING BETWEEN EXPRESSIONS; WR_S2←" ";
COMMENT SET SPACING BETWEEN ARRAY ELEMENTS; WR_S3←TAB;
COMMENT SET SPACING BETWEEN SET & LIST ITEMS; WR_S4←", ";

WR_INI("DSK","OUTPUT.OUT",GETCHAN,50);
WRITEON(J,PI,ITV,GREET,DATUM(ITA);
WRITEON(S,L,25,SQRT(3.),{},GREET & GREET);
WRITEON EVENS,CRLF&"SAY YOUR ABC's",ALPHABET);
CLOSE(WR_CHN)
END "WRTEST"

The file OUTPUT.OUT, after the program is run:

7  3.141593     ITA HELLO 117
{ITA, ITB} {{ITA, ITB, ITEM_11}} 25  1.732051     
PHI HELLOHELLO
0       2       4       6       8       10      12
        14      16      18 
SAY YOUR ABC's A        B       C       D       E
        F       G       H       I       J       K
        L       M       N       O       P       Q
        R       S       T       U       V       W
        X       Y       Z




6.3 - Runtime particulars
      _______ ___________


The WRITEON runtime keeps track of the print length of the line being
assembled.  If  a string to  be concatenated to  the end of  the line
would cause the print length to exceed MAXLENGTH characters, then the
runtime inserts  a CRLF and  resets its counter  before concatenating
the string.

Example:  Suppose MAXLENGTH is 50, there are 35 characters already in
the line,  and the  runtime is asked  to concatenate  a string  of 21


                                 15
SAIL Addendum  1                                              WRITEON


characters  to the  end  of the  line.  Since  35+21>50,  the runtime
concatenates a  CRLF, zeroes its  counter, and then  concatenates the
21-character string.   This produces  one line  of 35  characters and
another (as yet partial) line of 21 characters.  Suppose  the runtime
is  then  asked  to  concatenate  strings  of  58  characters  and 10
characters.  Since 21+58>50, the runtime concatenates a  CRLF, zeroes
its count, and concatenates the 58-character string.  Since 58+10>50,
the runtime concatenates a  CRLF, zeroes its count,  and concatenates
the 10-character string.  Thus there are lines of 35, 21, 58,  and (a
partial line of ) 10 characters.

The  runtime  will recognize  a  CRLF  contained in  a  string  to be
concatenated if the CRLF appears as either the first two or  the last
two characters (but it will  recognize only one CRLF if  CRLF appears
at both the beginning and end).  The runtime will recognize a  TAB in
a string to be concatenated if the TAB is the first character  of the
string.

The runtime routine contains several INTERNAL variables which control
the WRITEON environment.  The user may declare these EXTERNAL to look
at  them  or  change  their  values.   Variables  are  initialized to
0(FALSE) if integers and to NULL if strings.

Integer Variables       Function

    WR_TTK      Terminal kill flag.  If true, do not send 
                output to the terminal.

    WR_FIL      File flag.  If false, do not send output to 
                DEVICE:FILE of WR_INI.

    WR_LEN      Maximum line length before CRLF is inserted.
                (MAXLENGTH is copied to this location.)

    WR_CHN      Channel number for file output.
                (CHANNEL is copied to this location.)

    WR_ACT      Activation control--when to actually do the
                output to the terminal or file.
                =0   at the end of the WRITEON statement
                =1   after each inserted or recognized CRLF
                ≥2   after each expression in the WRITEON
                ≥3   after each element of an array, set, or list

    WR_USR      If ≠0, the location of a SIMPLE procedure to be
                called instead of OUTSTR and OUT to dispose of
                the current line.  This procedure should be
                declared like SIMPLE PROCEDURE GOBBLE(STRING S).

                                 16
SAIL Addendum  1                                              WRITEON


                Then say EXTERNAL INTEGER WR_USR;
                WR_USR←LOCATION(GOBBLE).

    WR_LPK      Leap name killer.  If true then the empty set
                prints as {}, the empty list as {{}}, and
                the items ANY, BINDIT, MAINPI, and EVENT_TYPE
                are not treated in any special manner.

    WR_CUR      "Cursor" position.  This variable holds the print
                length of the current line.

String Variables        Function

    WR_S1       Concatenated to the end of the line after
                each WRITEON statement.

    WR_S2       Inserted into the line between each expression
                appearing in the WRITEON statement.

    WR_S3       Inserted into the line between consecutive
                elements of the same array.

    WR_S4       Inserted into the line between consecutive
                items in the same set or list.

    WR_ST       This is the current line being assembled.
                If WR_USR≠0, then the call to the user
                procedure is   user_proc(WR_ST).


All CVS and CVG calls are done with the current settings or WIDTH and
DIGITS (see SETFORMAT).

To minimize the  number of string  concatenations (at the  expense of
calls to OUTSTR  and OUT), use WR_ACT←3.   To minimize the  number of
calls to OUTSTR and OUT (at the expense of string concatenations) use
WR_ACT←0 (the default).

To use multiple channels, non-Stanford I/O structures, etc:

A.  Do the I/O initializations for each file/channel.  A standard OPEN
    and ENTER sequence may be done for each file simply by calling
    WR_INI several times (once for each file/channel).

B.  Set WR_FIL←TRUE and WR_LEN←<length>.

C.  To switch channels, save and restore the values of parameters that
    are pecular to each channel, then do the WRITEON.  The values

                                 17
SAIL Addendum  1                                              WRITEON


    which normally will need to be saved and restored are WR_ST,
    WR_CUR, and WR_CHN.  Here is one way to do this:

    PROCEDURE SWITCH_CHAN(INTEGER NEWCHAN);
    BEGIN OWN INTEGER ARRAY CURSOR[0:20]; OWN STRING ARRAY STR[0:20];
    EXTERNAL INTEGER WR_CUR,WR_CHN; EXTERNAL STRING WR_ST;

    IF NEWCHAN=WR_CHN THEN RETURN;
    CURSOR[WR_CHN]←WR_CUR; STR[WR_CHN]←WR_ST;
    WR_CUR←CURSOR[NEWCHAN]; WR_ST←STR[NEWCHAN]; WR_CHN←NEWCHAN
    END;
        .
        .
        .
    SWITCH_CHAN(<new channel number>);
    WRITEON(<whatever>);





6.4 - Using WRITEON for other purposes
      _____ _______ ___ _____ ________


At  compile  time  SAIL constructs  a  one-word  descriptor  for each
expression appearing in the WRITEON statement.  These descriptors are
fed one at a time to the runtime routine WR_TON, which interprets the
descriptors  in the  appropriate manner.   After all  the expressions
appearing in the WRITEON statement have been processed,  the compiler
inserts an extra call to  WR_TON with an all zero descriptor  to flag
the end of the WRITEON statement.

The descriptor of an expression is identical to the datum which would
be produced by  REF_ITEM of the  expression; WRITEON does  not create
new items.  The format of a descriptor is:














                                 18
SAIL Addendum  1                                              WRITEON



Bits    Name    Comment

    1   REFB    "Reference" bit.  If this bit is on, then the
                address field points to a "permanent" location.
                If this bit is off, then the address field points
                to a temporary location.  Temporaries may be
                reused by the compiler within the same WRITEON.

    2   QUESB   On if ? itemvar.

    3   BINDB   On if BINDING itemvar.

    4   PROCB   "Procedure" bit.

    5   ITEMB   On if item or itemvar.


    6   ARY2B   On if λ array itemvar array.

 7-12   MSK6BT  Type code, same as LEAP datum type (see TYPEIT).

13-35   ADDR    Effective address which points at the object
                referred to.  String temporaries reside on top
                of the string stack (ADDR is  SP,,0).  All
                other objects reside in fixed memory locations
                (ADDR is  0,,address).  The address of an array
                is the address of its HEAD word (see SAIL manual,
                p.106).


By writing his own routine  named WR_TON the user may do  anything he
wants with the descriptors.

Caution.  In the  case of a string  temporary, the user must  pop the
stack.  The locations housing other temporaries may possibly  be used
more than once within the same WRITEON.












                                 19
SAIL Addendum  1                           MISCELLANEOUS NEW FEATURES


                             SECTION  7
                             _______  _

                     MISCELLANEOUS NEW FEATURES
                     _____________ ___ ________







7.1 - NEW MTAPE OPTIONS
      ___ _____ _______


        MTAPE(chan,NULL)


will cause an MTAPE 0 to be issued for channel chan.  For mag. tapes,
this will  cause you to  wait until all  activity ceases.   For other
devices, various  random things can  happen, depending on  the device
and system.

In export SAIL, MTAPE(chnl,"I") sets the 'IBM compatible' mode  for a
tape drive.  (It does an MTAPE chnl,101.)



7.2 - INITIALIZATION PHASES
      ______________ ______


User initializations  are  now done  in successive  phases, with  all
initializations   required   for   one   phase   being  done   before
initializations required for the next phase.

Syntax:

        REQUIRE <procid> INITIALIZATION;
        REQUIRE <procid> INITIALIZATION [<phase no>];

where <phase no> is an integer constant.

Semantics:

<phase no> specifies  the number  of the user   initialization phase.
If  it is left out,   then one is used.   Currently, there  are three
phases,  numbered 0,  1, and   2.  If  the  demand  is  great enough,
additional phases may  be added later.   (Note for assembly  language
hackers: internally, user phases are numbered '400000, '400001, etc.)


                                 20
SAIL Addendum  1                           MISCELLANEOUS NEW FEATURES


7.3 - CHNCDB
      ______


        val←CHNCDB(channel)

This integer procedure returns a pointer to the three word block used
to open the  specified channel.   It is provided  for the benefit  of
assembly language procedures that may want to do I/O inside some fast
inner loop, but which may want to live in a SAIL core image & use the
SAIL OPEN, etc.



7.4 - ARRCLR
      ______


        ARRCLR(arry)

This new runtime routine clears any kind of array. That is, arthmetic
arrays get filled with  zeros, string arrays with NULLs,  and itemvar
arrays with ANYs.  One may  use ARRCLR with set and list  arrays, but
the set  and list space  will be lost  (i.e. un-garbage-collectable).
The alternative form:

        ARRCLR(arry,val)


where val is either an integer or a real number, will fill  arry with
that value.  Do not  do this to string  or list arrays unless  you do
not care whether  or not your program  works.  Also using a  real val
for an itemvar array is apt to cause strange results. (If you  use an
integer, arry will be filled with CVI(val).)



7.5 - SETPL
      _____


        SETPL(channel, @linnum, @pagnum, @sosnum)

This new runtime routine allows one to keep track of the string input
from CHANNEL.  Whenever a '12 is encountered, LINNUM  is incremented.
Whenever a '14 is  encountered, PAGNUM is incremented, and  LINNUM is
zeroed.  Whenever  an SOS  line number is  encountered, it  is placed
into SOSNUM.  When  fully implemented (soon),  this will work  on the
INPUT, INTIN, and REALIN functions as well.



                                 21
SAIL Addendum  1                           MISCELLANEOUS NEW FEATURES


7.6 - EVALREDEFINE
      ____________


EVALREDEFINE bears  the same relationship  to REDEFINE  as EVALDEFINE
does to DEFINE.  See pages 47 and 50 of the Manual.



7.7 - CVPS
      ____


CVPS(<macro_parameter>)  converts <macro_parameter>  to a  string and
returns the  string. See  about macro  parameters on  page 48  of the
manual.



7.8 - EXPRESSIONS IN REQUIRES
      ___________ __ ________


Previously,  all REQUIRE  constructs had  to have  only  constants in
them. Now  SAIL allows  compile time expressions  as well.  See about
compile time expressions on page 47 of the Manual.



7.9 - RELEASE
      _______


RELEASE  now takes  an optional  second argument,  the  CLOSE inhibit
bits.  These are described in the UUO manual (Stanford System). These
are defaulted to zero when  not specified so that old  programs which
did not specify them will work as before.



7.10 - TTYUP
       _____


        oldval←TTYUP(newval)


This  routine casuse  conversion of  lower case  characters  (a-z) to
their upper  case equivalents  for strings  read by  any of  the SAIL
teletype routines that do not  use break tables.  If newval  is TRUE,
then conversion will take place on all subsequent inputs  until TTYUP
is called with newval FALSE.  Oldval will always get set to the value


                                 22
SAIL Addendum  1                           MISCELLANEOUS NEW FEATURES


of newval used in the previous call. (If TTYUP has never been called,
then no conversions will take place, and the first call to TTYUP will
return FALSE).



7.11 - BREAKSET MODES "K" AND "F"
       ________ _____ ___ ___ ___


A "K" specification as a BREAKSET mode will cause lower to upper case
conversion when  that break  table is  used.  Conversion  takes place
before each character  is checked for  breaking or omission.   An "F"
specification turns off the conversion -- i.e. it undoes  the effects
of "K".



7.12 - INOUT
       _____


        INOUT(inchan,outchan,howmany)


INOUT reads howmany words from channel inchan and writes them  out on
channel outchan.  Each channel must  be open in a mode between  8 and
12.  on return,  the EOF variables for  the two channels will  be the
same as if ARRYIN & ARRYOUT  had been used.  If howmany is  less than
zero, then transfer  of data will  cease only upon  end of file  or a
device error.

(note: INOUT  uses BLTs  to transfer  data directly  from one  set of
buffers to the other)



7.13 - GETSTS & SETSTS
       ______ _ ______


        SETSTS(chan,new_status)

issues a SETSTS uuo on channel chan with the status value new_status.

        status←GETSTS(chan)


returns the results of a GETSTS uuo on channel chan.



                                 23
SAIL Addendum  1                           MISCELLANEOUS NEW FEATURES


7.14 - CHANGES TO "OPEN" ERROR HANDLING
       _______ __ ______ _____ ________


If the EOF variable supplied to OPEN is non-zero and the  device name
is  invalid, then  OPEN will  fail without  giving the  error message
"INVALID DEVICE NAME FOR OPEN", and the EOF value will  be unchanged.
If a device is unavailable, and EOF=0, then the user is now given the
options of trying  again or going on  without opening the  device, in
which case EOF will be set to non-zero as usual.



7.15 - ASH
       ___


ASH has  been added as  an arithmetic operator.   Its syntax  is just
like that of LSH, and  it generates similar code (except  for putting
out a PDP-10 ASH instruction instead of a LSH).



7.16 - ARG_LIST
       ________


        ARG_LIST(<arg1>,...,<argn>)


where each <arg> may be any valid argument to the REF_ITEM construct,
assembles a list of "temporary" reference items that will  be deleted
by APPLY after the applied procedure returns.  Thus

        APPLY(proc,ARG_LIST(foo,bar,VALUE baz))

is roughly equivalent to

        tmplst←{{REF_ITEM(foo),REF_ITEM(bar),REF_ITEM(VALUE baz)}};
        APPLY(proc,tmplst);
        WHILE LENGTH(tmplst) DO DELETE(LOP(tmplst));


but  is  somewhat easier  to  type.  Note  that  the  reference items
created by ARG_LIST are  just like those created by  REF_ITEM, except
that they are marked so that APPLY will know to kill them.






                                 24